using Jupiter.Infrastructure;
using Jupiter.Infrastructure.Cache.Interfaces;
using Jupiter.Infrastructure.Domain;
using Jupiter.Infrastructure.Domain.SqlSugar;
using Jupiter.Infrastructure.Domain.SqlSugar.Basic;
using Jupiter.Infrastructure.Exceptions;
using Jupiter.Infrastructure.Mappings;
using Jupiter.Infrastructure.Permission;
using Jupiter.Infrastructure.Permission.DataPermissions;
using MediatR;
using Microsoft.Extensions.Configuration;
using Wips.AppService.Authorities.Permissions.Requests;
using Wips.AppService.Authorities.Roles.Requests;
using Wips.Domain.Models.Authorities.Model;

namespace Wips.AppService.SqlSugar.Authorities.Roles
{
    /// <summary>
    /// 角色请求处理程序
    /// </summary>
    public class RoleRequestHandler :
        RequestHandlerBase<Role>,
        IRequestHandler<CreateRoleRequest, string>,
        IRequestHandler<UpdateRoleRequest, string>,
        IRequestHandler<DeleteRoleRequest, string>,
        IRequestHandler<AssignPositionsForRoleRequest, bool>,
        IRequestHandler<RoleStatusChangeRequest, string>,
        IRequestHandler<InitAdminRoleRequest, string>
    {
        private readonly IMapsterMapper _mapper;

        private readonly IMediator _mediator;
        // private readonly ICapPublisher _capPublisher;


        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> Handle(CreateRoleRequest request,
            CancellationToken cancellationToken)
        {
            // 封装实体对象
            var entity = _mapper.MapTo<Role>(request);
            entity.Id = ObjectId.GenerateNewStringId();
            entity.CreatorId = UserId!;
            entity.LastUpdatedUserId = UserId;
            entity.TenantId = TenantId;
            await RegisterNewAsync(entity, cancellationToken);
        

            return entity.Id;
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<string> Handle(UpdateRoleRequest request,
            CancellationToken cancellationToken)
        {
            // 封装实体对象
            var entity = await Query()
                .FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);

            if (entity == null)
            {
                throw new CoreException("找不到记录");
            }

            entity.Name = request.Name;
            entity.Remarks = request.Remarks;
            entity.LastUpdatedUserId = UserId;

            // 更新
            RegisterDirty(entity);
       
          


            return entity.Id!;
        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="CoreException"></exception>
        public async Task<string> Handle(DeleteRoleRequest request,
            CancellationToken cancellationToken)
        {
            // 封装实体对象
            var entity = await Query()
                .FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);
            if (entity == null)
            {
                throw new CoreException("找不到要删除的数据");
            }


            // 删除
            RegisterDelete(entity);

            return entity.Id!;
        }

        /// <summary>
        /// 分配角色
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        /// <exception cref="CoreException"></exception>
        public async Task<bool> Handle(AssignPositionsForRoleRequest request,
            CancellationToken cancellationToken)
        {
            // 封装实体对象
            var entity = await Query()
                .FirstOrDefaultAsync(p => p.Id == request.RoleId, cancellationToken);

            if (entity == null)
            {
                throw new CoreException("找不到记录");
            }

            // 读取旧的职位角色关联数据
            RegisterDeleteObjectValueRange<PositionRole>(p => p.RoleId == request.RoleId);

            // 创建新的关联数据
            var news = request
                .PositionIds
                .Select(positionId => new PositionRole(positionId, request.RoleId))
                .ToList();
            // 批量新增
            await RegisterNewObjectValueRangeAsync(news, cancellationToken: cancellationToken);
            // 重构缓存
            // await _capPublisher.PublishAsync(AuthorityTopicNames.RolePermissionAssignedEvent,
            //     new RolePermissionAssignedEvent(entity.Id), cancellationToken: cancellationToken);
            return true;
        }

        /// <summary>
        /// 状态变更
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> Handle(RoleStatusChangeRequest request,
            CancellationToken cancellationToken)
        {
            // 封装实体对象
            var entity = await Query()
                .FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken);

            if (entity == null)
            {
                throw new CoreException("找不到记录");
            }

            // 变更状态
            entity.StatusChange(UserId);
            // 更新
            RegisterDirty(entity);

            return entity.Id!;
        }


        /// <summary>
        /// 初始化管理员角色
        /// </summary>
        /// <param name="request"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<string> Handle(InitAdminRoleRequest request, CancellationToken cancellationToken)
        {
            var adminRole = await Query()
                .Filter(null, true)
                .Where(c => c.RoleType == EnumRoleType.Admin)
                .FirstOrDefaultAsync(cancellationToken);
            if (adminRole == null)
            {
                adminRole = new Role()
                {
                    RoleType = EnumRoleType.Admin,
                    Id = ObjectId.GenerateNewStringId(),
                    Name = "管理员",
                    Status = Status.Enabled,
                };
                await RegisterNewAsync(adminRole, cancellationToken);
            }

         

            var allMenus = await Query<Menu>()
                .Filter(null, true)
                .Where(c => c.Status == Status.Enabled)
                .Select(c => new { c.Id })
                .ToListAsync(cancellationToken);
            var allOperations = await Query<Operation>()
                .Filter(null, true)
                .Select(c => new { c.Id })
                .ToListAsync(cancellationToken);
       
                var response = await _mediator.Send(new AddPermissionRequest
                {
                    RoleId = adminRole.Id,
             
                }, cancellationToken: cancellationToken);
                if (!response)
                {
                    throw new CoreException("权限初始化错误！");
                }
        


            return "";
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="securityContextAccessor"></param>
        /// <param name="facadeResolver"></param>
        /// <param name="cacheManager"></param>
        /// <param name="configuration"></param>
        /// <param name="mapper"></param>
        /// <param name="mediator"></param>
        /// <param name="dataPermission"></param>
        public RoleRequestHandler(ISqlSugarClient dbContext, ISecurityContextAccessor securityContextAccessor,
            IFacadeResolver facadeResolver, ICacheManager cacheManager, IConfiguration configuration,
            IMapsterMapper mapper, IMediator mediator, IDataPermission dataPermission) : base(
            dbContext, securityContextAccessor, facadeResolver, cacheManager, configuration, dataPermission)
        {
            _mapper = mapper;
            _mediator = mediator;
        }
    }
}